## 第三版
class Node:
    def __init__(self, value, next=None, prev=None):
        self.value = value
        self.next = next
        self.prev = prev
    
    def __repr__(self):
#         return "{} <-- {} --> {}".format(
#             self.prev.value if self.prev else None, 
#             self.value, 
#             self.next.value if self.next else None
#         )
        return f'{self.value}'

    
class LinkList:
    '''还可以在完善下'''
    __slots__ = 'head tail length'.split()
    def __init__(self):
        self.head = None
        self.tail = None
        self.length = 0
        
    def insert(self, index, value):
        '''找个位置插入''' 
        # 索引改成正的   
        index = index if index >= 0 else self.length + index
        if index >= self.length:
            self.append(value)
            return
        if index < 0:
            index = 0
        current = self[index]
        prev = current.prev
        next = current.next
        # 尾巴插入
        if next is None:
            self.append(value)
            return 
        node = Node(value)
        # 头插入
        if prev is None:             
            self.head = node
            node.next = current
            current.prev = node
        # 中间插入
        else:
            prev.next = node
            node.prev = prev
            node.next = current
            current.prev = node
        self.length += 1
        
    def append(self, value):
        '''尾部追加'''
        node = Node(value)
        if self.head is None:           
            self.head = node 
        else:
            self.tail.next = node
            node.prev = self.tail
        self.tail = node
        self.length += 1
        return self
    
    def pop(self):
        '''尾部删除'''
        if self.length == 0:
            raise Exception('Empty')
        current = self[self.length-1]
        prev = current.prev
        self.tail = prev
        prev.next = None
        self.length -= 1
        return current.value
 
    def remove(self, index):
        '''移除某个位置的'''
        if self.length == 0:
            raise Exception('Empty')
        current = self[index]
        prev = current.prev
        next = current.next
        # 只有一个元素了
        if prev is next:
            self.tail = None
            self.head = None
        # 移除第一个元素，要移除的是第一个
        elif prev is None:
            self.head = next
            next.prev = None
        # 移除最后一个元素，
        elif next is None:
            self.tail = prev
            prev.next = None
        # 在中间删除
        else:
            prev.next = next
            next.prev = prev
        self.length -= 1
   
    def iterlink(self, reverse=False):
        '''支持一个遍历的方法'''
        current = self.tail if reverse else self.head
        while current:
            yield current
            current = current.prev if reverse else current.next
    
    def __len__(self):
        '''可以求得长度'''
        return self.length
    
    def __iter__(self):
        '''实例本身就可以迭代，使用更方便'''
        return self.iterlink()
    
    def __setitem__(self, index, value):
        '''可以直接用中括号的方式进行赋值'''
        node = Node(value)
        current = self[index]
        prev = current.prev
        next = current.next
        # 头插入
        if prev is None:
            self.head = node
            node.next = current
            current.prev = node
        # 中间插入，前后都不是None
        elif prev and next:
            prev.next = node
            node.prev = prev
            node.next = current
            current.prev = node
        # 尾部插入
        else:
            self.tail = node
            node.prev = current
            current.next = node
        self.length += 1
    
    def __getitem__(self, index):
        '''支持中括号式访问'''
        # 都转换成正索引
        index =index if index >= 0 else self.length + index
        if index < 0 or index > self.length:
            raise IndexError('Index exceeded')
        for i, item in enumerate(self):
            if index == i:
                return item

ll = LinkList()
# ll.append(1).append('iiii').append(3)#.append(1214)
# ll.insert(0, 0)
# ll.insert(10, 10)
# ll.insert(-10, 11)
# ll.insert(-3, 'hahaha')
# ll.insert(2, 'wahahaha')
# for i in ll:
#     print(i)
# len(ll)
